package com.atguigu.gmall.order.receiver;

import com.atguigu.gmall.common.rabbit.config.MqConst;
import com.atguigu.gmall.enums.model.OrderStatus;
import com.atguigu.gmall.enums.model.ProcessStatus;
import com.atguigu.gmall.order.model.OrderInfo;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Author: 小兰
 * @Date: 2023/5/9 20:01
 */
@Component
@Slf4j
public class OrderReceiver {
    @Autowired
    private OrderInfoService orderInfoService;

    /**
     * 监听处理延迟关闭订单消息
     * @param orderId
     * @param channel
     * @param message
     */

    @SneakyThrows
    @RabbitListener(queues = {MqConst.QUEUE_ORDER_CANCEL})
    public void processOrderClose(Long orderId, Channel channel, Message message){
            if (orderId!=null){
                log.info("[订单服务]监听关单消息,数据:{}", orderId);
                //调用业务层关闭订单
                OrderInfo orderInfo = orderInfoService.getById(orderId);
                //判断订单状态只有 未支付订单 才会进行关闭
                if (orderInfo!=null && OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())
                     && OrderStatus.UNPAID.name().equals(orderInfo.getProcessStatus())){
                    orderInfoService.execExpiredOrder(orderId);
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    /**
     * 监听用户支付成功消息,修改订单状态,发送锁定库存消息到库存服务
     * @param orderId
     * @param channel
     * @param message
     */
    @SneakyThrows
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_PAY,durable = "true"),
                    value = @Queue(value = MqConst.QUEUE_PAYMENT_PAY,durable = "true"),
                    key = MqConst.ROUTING_PAYMENT_PAY
            )
    )
    public void processPaySuccessResult(Long orderId,Channel channel,Message message){
        try {
            if (orderId!=null){
                log.info("[订单服务]监听用户支付成功消息,订单ID:{}", orderId);
                //1.根据订单id查询订单记录,
                OrderInfo orderInfo = orderInfoService.getById(orderId);
                if (orderInfo!=null && ProcessStatus.UNPAID.name().equals(orderInfo.getOrderStatus())) {
                //2.更新订单支付状态: 已支付
                    orderInfoService.updateOrderStatus(orderId,ProcessStatus.PAID);

                //3.todo 发送消息到第三方库存系统 完成锁定商品库存
                }

            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            //todo 重新入对,让MQ服务器再次投递消息,做好最大次数限制,做好幂等性处理
            log.error("[订单服务]监听用户支付成功消息,处理失败:{}", e);
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            throw new RuntimeException(e);
        }
    }
}
